﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Globalization;
using System.Text.RegularExpressions;

namespace PhotoGallery.Infrastructure.Helpers
{
    public static class StringHelper
    {
        private static readonly Regex RegStripHtml = new Regex("<[^>]*>", RegexOptions.Compiled);
        private static readonly string emailReg = @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
        private static readonly char[] characters = new char[] {
                'a', 'b', 'c', 'd', 'e', 'f', 'g',
                'h', 'i', 'j', 'k', 'l', 'm', 'n',
                'o', 'p', 'q', 'r', 's', 't',
                'u', 'v', 'w', 'x', 'y', 'z',
                'A', 'B', 'C', 'D', 'E', 'F', 'G',
                'H', 'I', 'J', 'K', 'L', 'M', 'N',
                'O', 'P', 'Q', 'R', 'S', 'T',
                'U', 'V', 'W', 'X', 'Y', 'Z',
                '0', '1', '2', '3', '4', '5',
                '6', '7', '8', '9'
            };

        /// <summary>
        /// 验证字符串是否为邮件格式
        /// </summary>
        /// <param name="text">文本</param>
        public static Boolean IsEmail(this String text)
        {
            if (string.IsNullOrEmpty(text))
            {
                throw new ArgumentNullException("text");
            }

            return System.Text.RegularExpressions.Regex.IsMatch(text, emailReg);
        }

        /// <summary>
        /// 移除字符串中的HTML标签
        /// </summary>
        public static string StripHtml(string html)
        {
            if (string.IsNullOrEmpty(html))
                return string.Empty;

            return RegStripHtml.Replace(html, string.Empty);
        }

        /// <summary>
        /// 移除非法字符
        /// </summary>
        public static String RemoveIllegalCharacters(String text)
        {
            if (string.IsNullOrEmpty(text))
                return text;

            text = text.Replace(":", string.Empty);
            text = text.Replace("/", string.Empty);
            text = text.Replace("?", string.Empty);
            text = text.Replace("#", string.Empty);
            text = text.Replace("[", string.Empty);
            text = text.Replace("]", string.Empty);
            text = text.Replace("@", string.Empty);
            text = text.Replace("*", string.Empty);
            text = text.Replace(".", string.Empty);
            text = text.Replace(",", string.Empty);
            text = text.Replace("\"", string.Empty);
            text = text.Replace("&", string.Empty);
            text = text.Replace("'", string.Empty);
            text = text.Replace(" ", "-");

            text = RemoveDiacritics(text);
            text = RemoveExtraHyphen(text);

            return text;
            //return HttpUtility.UrlEncode(text).Replace("%", string.Empty);
        }

        /// <summary>
        /// Escape string.
        /// </summary>
        public static String EscapeString(String text)
        {
            StringBuilder sb = new StringBuilder();

            byte[] ba = System.Text.Encoding.Unicode.GetBytes(text);
            for (int i = 0; i < ba.Length; i += 2)
            {
                sb.Append("%u");
                sb.Append(ba[i + 1].ToString("X2"));

                sb.Append(ba[i].ToString("X2"));
            }
            return sb.ToString();
        }

        private static string RemoveExtraHyphen(string text)
        {
            if (text.Contains("--"))
            {
                text = text.Replace("--", "-");
                return RemoveExtraHyphen(text);
            }

            return text;
        }

        private static String RemoveDiacritics(string text)
        {
            String normalized = text.Normalize(NormalizationForm.FormD);
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < normalized.Length; i++)
            {
                Char c = normalized[i];
                if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
                    sb.Append(c);
            }

            return sb.ToString();
        }

        /// <summary>
        /// 截取字符串
        /// </summary>
        /// <param name="str">要截取的字符串</param>
        /// <param name="length">截取长度</param>
        /// <param name="endStr">结尾处理(如：取值"...",截取后将在结尾加"...",算在截取长度内)</param>
        /// <returns></returns>
        public static string CutString(string str, int length, string endStr)
        {
            string temp = str.Substring(0, (str.Length < length + 1) ? str.Length : length + 1);
            byte[] encodedBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(temp);

            string outputStr = String.Empty;
            int count = 0;

            for (int i = 0; i < temp.Length; i++)
            {
                if ((int)encodedBytes[i] == 63)
                    count += 2;
                else
                    count += 1;

                if (count <= length - endStr.Length)
                    outputStr += temp.Substring(i, 1);
                else if (count > length)
                    break;
            }

            if (count <= length)
            {
                outputStr = temp;
                endStr = String.Empty;
            }

            outputStr += endStr;

            return outputStr;
        }

        public static string HTMLEncode(string str)
        {
            str = str.Replace("&", "&amp;");
            str = str.Replace("'", "&acute;");
            str = str.Replace("\"", "&quot;");
            str = str.Replace(">", "&gt;");
            str = str.Replace("<", "&lt;");

            return str;
        }

        public static string HTMLDecode(string str)
        {
            str = str.Replace("&acute;", "'");
            str = str.Replace("&quot;", "\"");
            str = str.Replace("&ldquo;", "“");
            str = str.Replace("&rdquo;", "”");
            str = str.Replace("&gt;", ">");
            str = str.Replace("&lt;", "<");
            str = str.Replace("&amp;", "&");
            return str;
        }

        /// <summary>
        /// 生成随机的文本
        /// </summary>
        /// <param name="length">生成字符串的长度</param>
        public static String GenerateRandomText(UInt32 length)
        {
            StringBuilder sb = new StringBuilder();
            Random r = new Random(DateTime.Now.Millisecond);

            int pos = 0;
            for (int i = 0; i < length; i++)
            {
                pos = r.Next(0, 62);
                sb.Append(characters[pos]);
            }

            return sb.ToString();
        }

        public static void WriteCharAsUnicode(TextWriter writer, char c)
        {
            if (writer == null)
            {
                throw new ArgumentNullException("writer");
            }

            char h1 = MathHelper.IntToHex((c >> 12) & '\x000f');
            char h2 = MathHelper.IntToHex((c >> 8) & '\x000f');
            char h3 = MathHelper.IntToHex((c >> 4) & '\x000f');
            char h4 = MathHelper.IntToHex(c & '\x000f');

            writer.Write('\\');
            writer.Write('u');
            writer.Write(h1);
            writer.Write(h2);
            writer.Write(h3);
            writer.Write(h4);
        }

        public static StringWriter CreateStringWriter(int capacity)
        {
            StringBuilder sb = new StringBuilder(capacity);
            StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture);

            return sw;
        }

        public static int? GetLength(string value)
        {
            if (value == null)
                return null;
            else
                return value.Length;
        }
    }
}
